package cn.exrick.xboot.modules.base.serviceimpl.mybatis;

import cn.exrick.xboot.base.XbootBaseEntity;
import cn.exrick.xboot.common.constant.CommonConstant;
import cn.exrick.xboot.common.exception.ServiceException;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.factory.MyBeanFactory;
import cn.exrick.xboot.modules.base.dao.mapper.OrganizationMapper;
import cn.exrick.xboot.modules.base.entity.Organization;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.enums.OrganizationExceptionEnum;
import cn.exrick.xboot.modules.base.param.OrganizationParam;
import cn.exrick.xboot.modules.base.service.mybatis.IOrganizationService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 *  njp 20201105
 *   暂时不使用这个做为系统的组织
 *   因部门与权限逻辑完整直接采用部门作为系统的组织结构,同时系统中也不需要部门
 * 组织机构接口实现
 * @author njp
 */
@Slf4j
@Service
@Transactional
public class IOrganizationServiceImpl extends ServiceImpl<OrganizationMapper, Organization> implements IOrganizationService {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(OrganizationParam organizationParam) {
        checkParam(organizationParam);
        Organization org = MyBeanFactory.getMyBeanFactory().createBean(Organization.class);
        //克隆对象
        CopyOptions copyOptions=new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        organizationParam.setId(null);
        //添加默认排序字段
        org.setSortOrder(new BigDecimal(0));
        BeanUtil.copyProperties(organizationParam, org,copyOptions);
        this.save(org);
        // 同步该节点缓存
        Set<String> keys = redisTemplate.keys(CommonConstant.orgCache +org.getParentId()+":*");
        redisTemplate.delete(keys);
        // 如果不是添加的一级 判断设置上级为父节点标识
        if(!CommonConstant.PARENT_ID.equals(organizationParam.getParentId())){
            Organization parent = this.getById(org.getParentId());
            if(parent==null){
                throw new ServiceException(OrganizationExceptionEnum.ORG_PARENT_IS_NO);
            }
            if(parent.getIsParent()==null||!parent.getIsParent()){//设置父级的状态值
                parent.setIsParent(true);
                this.saveOrUpdate(parent);
                // 更新上级节点的缓存
                Set<String> keysParent = redisTemplate.keys(CommonConstant.orgCache+parent.getParentId()+":*");
                redisTemplate.delete(keysParent);
            }
        }

    }

    @Override
    public List<Organization> getByParentId(OrganizationParam organizationParam) {
        LambdaQueryWrapper<Organization> queryWrapper=new LambdaQueryWrapper();
        String id=organizationParam.getId();
        if(id==null){
            return new ArrayList<Organization>();
        }
        queryWrapper.eq(Organization::getParentId,id);
        queryWrapper.orderByDesc(Organization::getSortOrder);
        System.out.println(queryWrapper.getCustomSqlSegment());
        return this.list(queryWrapper);
    }

    @Override
    public void edit(OrganizationParam organizationParam) {
        if(ObjectUtil.isNull(organizationParam.getId())||ObjectUtil.isEmpty(this.getById(organizationParam.getId()))){
            throw  new ServiceException(OrganizationExceptionEnum.ORG_ID_IS_NOTNULL);
        }
        CopyOptions copyOptions=new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        Organization organization = MyBeanFactory.getMyBeanFactory().editBean(Organization.class);
        BeanUtil.copyProperties(organizationParam,organization,copyOptions);
        this.saveOrUpdate(organization);
    }

    @Override
    public void delete(OrganizationParam organizationParam) {
        //检查是否有子节点
         if(getByParentId(organizationParam).size()>0){
             throw new ServiceException(OrganizationExceptionEnum.ORG_DEL_IS_NOTNULL);
         }
        //todo 检查该组织有没有被其他地方引用（用户引用，权限引用）
       //目前先只做根据id查询，后期根据情况进行扩展 njp
        if(ObjectUtil.isNull(organizationParam.getId())||ObjectUtil.isEmpty(this.getById(organizationParam.getId()))){
                throw new ServiceException(OrganizationExceptionEnum.ORG_ID_IS_NOTNULL);
        }
        this.removeById(organizationParam.getId());
    }

    @Override
    public List<Organization> search(String title) {
        LambdaQueryWrapper<Organization> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.like(Organization::getTitle,title);
        queryWrapper.orderByDesc(Organization::getSortOrder);
       return this.list(queryWrapper);
    }

    private void checkParam(OrganizationParam organizationParam){
        if(!ObjectUtil.isNotNull(organizationParam.getParentId())){
            throw new ServiceException(OrganizationExceptionEnum.ORG_PARENT_NOT_NULL);
        }
    }
}